package io.hepu.robotize.http;

import lombok.Data;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.util.EntityUtils;

import java.io.Serializable;
import java.nio.charset.StandardCharsets;
import java.util.Optional;

/**
 * Simple generic http response
 *
 * @param <T> the type of response body
 */
@Data
public class HttpResult<T> implements Serializable {
    // 状态码
    private int code;

    // 响应体
    private T body;

    public HttpResult(int code, T body) {
        this.code = code;
        this.body = body;
    }

    public static <T> HttpResult<T> of(int code, T body) {
        return new HttpResult<>(code, body);
    }

    public static <T> HttpResult<T> ok(T body) {
        return of(HttpStatus.SC_OK, body);
    }

    public static <T> HttpResult<T> fail(T body) {
        return of(HttpStatus.SC_BAD_REQUEST, body);
    }

    public static <T> HttpResult<T> unauthorized(T body) {
        return of(HttpStatus.SC_UNAUTHORIZED, body);
    }

    public static <T> HttpResult<T> notFound(T body) {
        return of(HttpStatus.SC_NOT_FOUND, body);
    }

    public static <T> HttpResult<T> forbidden(T body) {
        return of(HttpStatus.SC_FORBIDDEN, body);
    }

    public static <T> HttpResult<T> internalError(T body) {
        return of(HttpStatus.SC_INTERNAL_SERVER_ERROR, body);
    }

    public static <T> HttpResult<T> unavailable(T body) {
        return of(HttpStatus.SC_SERVICE_UNAVAILABLE, body);
    }

    public static <T> HttpResult<T> conflict(T body) {
        return of(HttpStatus.SC_CONFLICT, body);
    }

    public String getBodyAsString() throws Exception {
        if (this.body instanceof HttpEntity) {
            return EntityUtils.toString((HttpEntity) body, StandardCharsets.UTF_8);
        }
        return Optional.ofNullable(this.body).map(Object::toString).orElse(null);
    }

    @Override
    public String toString() {
        return "HttpResult [code=" + code + ", body=" + body + "]";
    }
}
